<script setup lang="ts">
defineOptions({
  name: "search"
});

import { ref, reactive, onMounted, watch, computed } from "vue";
import dayjs from "dayjs";
import { getMaterialTreeData } from "@/api/modules/fab";
import { areaes } from "../constant";

const periodOption: Array<{ label: string; value: string; disabled?: boolean }> = [
  {
    label: "过去一天",
    value: "day"
  },
  {
    label: "过去一周",
    value: "week"
  },
  {
    label: "过去一个月",
    value: "month"
    // disabled: true
  }
];

const datOption = reactive<Array<{ label: string; value: string; disabled: boolean }>>([
  {
    label: "实际值",
    value: "consumeValue",
    disabled: false
  },
  {
    label: "供给值",
    value: "supplyValue",
    disabled: false
  },
  {
    label: "设定值",
    value: "setValue",
    disabled: false
  }
]);

const realAreaes = ref<Array<Record<string, any>>>([]);
const loading = ref<boolean>(false);

// "day" | "week" | "month"
const period = defineModel("period", { type: String, default: "week" });

// type   area 区域     craft 工艺
const props = withDefaults(
  defineProps<{
    type: "area" | "craft";
    startTime?: string;
    endTime?: string;
    parameter?: string;
    dataTypesDisabled?: boolean;
  }>(),
  {
    type: "area",
    startTime: "",
    endTime: "",
    parameter: "",
    dataTypesDisabled: false
  }
);

interface Emits {
  /**
   * 所有搜索条件改变时触发
   * prams  搜索条件参数
   * types  数据选择
   * flag   是否首次触发  默认false
   * flag2  是否物料数据改变  默认false
   * flag3  是否从全不选到选择  默认false
   */
  (event: "change", prams?: Record<string, any>, types?: Array<string>, flag?: boolean, flag2?: boolean, flag3?: boolean): void;
  /**  物料选择 */
  (event: "selectChange", item?: Record<string, any>): void;
  /**  区域选择 */
  (event: "areaChange", item?: Record<string, any>): void;
  /**  数据选择 */
  (event: "typeChange", types?: Array<string>): void;
}

const emits = defineEmits<Emits>();

const defaultparameter = ref<Record<string, any>>({});

const searchParams = reactive<{ startTime: string; endTime: string; parameter: string }>({
  // 调试
  // startTime: dayjs("2024-08-01").format("YYYY-MM-DD HH:mm:ss"),
  // endTime: dayjs("2024-08-10").format("YYYY-MM-DD HH:mm:ss"),
  startTime: dayjs().subtract(7, "day").startOf("date").format("YYYY-MM-DD HH:mm:ss"),
  endTime: dayjs().endOf("date").format("YYYY-MM-DD HH:mm:ss"),
  // 调试
  // parameter: "GC01BG01AV01"
  parameter: ""
});

const defaultExpandedKeys = computed(() => [searchParams.parameter]);

const dataTypes = defineModel("dataTypes", {
  type: Array<string>,
  // default: () => ["实际值", "供给值", "设定值"]
  // 产品确认 默认去掉 设定值  供给值
  default: () => ["实际值"]
});

const cascaderTreeRef = ref(null);
const treeData = ref<Array<any>>([]);
const defaultProps = {
  children: "children",
  label: "name",
  disabled(data: any) {
    const { disabled = false } = data;
    return disabled;
  }
};

const getDefaultParameter = (item: any): Record<string, any> => {
  const { children = null } = item;
  if (children?.length) {
    return getDefaultParameter(children[0]);
  } else {
    return item;
  }
};

const getMapTreeData = (data: Array<any>, parameter?: string): Array<any> => {
  return data?.map(item => {
    let { children = null, materialList = [] } = item;
    if (children?.length) {
      item["disabled"] = true;
      item.children = getMapTreeData(item.children, parameter);
    } else {
      if (item?.materialList?.length) {
        item.code = item?.materialList[0]?.code;
        item["disabled"] = false;
      } else {
        item["disabled"] = true;
      }
    }
    if (materialList?.length && parameter && parameter === materialList[0]?.code) {
      defaultparameter.value = item;
    }
    if (!searchParams.parameter) {
      if (parameter) {
        searchParams.parameter = parameter;
      } else {
        if (materialList?.length) {
          // searchParams.parameter = materialList[0].code;
          defaultparameter.value = item;
        }
      }
    }
    return item;
  });
};

const initDate = () => {
  const { startTime = "", endTime = "" } = props;
  if (startTime) {
    searchParams.startTime = startTime;
  }
  if (endTime) {
    searchParams.endTime = endTime;
  }
};

const initTreeData = async (parameter?: string) => {
  loading.value = true;
  treeData.value.splice(0);
  let res = await getMaterialTreeData(null, () => {
    loading.value = false;
  });
  loading.value = false;
  res = getMapTreeData(res, parameter);
  res && treeData.value.push(...res);
};

const initAreaData = async (parameter?: string) => {
  realAreaes.value = Array.from(areaes.values());
  realAreaes.value.unshift({
    selected: true,
    label: "全部",
    value: "",
    backgroundColor: "#ccc"
  });
};

const startDisabledDateFn = (d: Date) => {
  const timeStamp = new Date(d).getTime();
  if (searchParams.endTime && timeStamp > dayjs(searchParams.endTime).valueOf()) return true;
  return false;
};

const endDisabledDateFn = (d: Date) => {
  const timeStamp = new Date(d).getTime();
  if (searchParams.startTime && timeStamp < dayjs(searchParams.startTime).valueOf()) return true;
  return false;
};

const periodChangeHandler = (val: any) => {
  let s = "";
  let e = dayjs().endOf("date").format("YYYY-MM-DD HH:mm:ss");
  switch (val) {
    case "day":
      s = dayjs().subtract(1, "day").startOf("date").format("YYYY-MM-DD HH:mm:ss");
      break;
    case "week":
      s = dayjs().subtract(7, "day").startOf("date").format("YYYY-MM-DD HH:mm:ss");
      break;
    case "month":
      s = dayjs().subtract(30, "day").startOf("date").format("YYYY-MM-DD HH:mm:ss");
      break;
    default:
      s = dayjs().subtract(7, "day").startOf("date").format("YYYY-MM-DD HH:mm:ss");
      break;
  }
  searchParams.startTime = s;
  searchParams.endTime = e;
  emits("change", getParams(), dataTypes.value);
};

const startTimeChangeHandler = (date: string) => {
  emits("change", getParams(), dataTypes.value);
};

const endTimeChangeHandler = (date: string) => {
  emits("change", getParams(), dataTypes.value);
};

const parameterChangeHandler = (val: any) => {
  const { code = "", value = "", disabled = false } = val;
  if (disabled) return;
  searchParams.parameter = code;
  emits("change", getParams(), dataTypes.value);
  emits("selectChange", val);
};

const areaChangeHandler = (item: any, index: number) => {
  for (const a of realAreaes.value) {
    a["selected"] = false;
  }
  realAreaes.value[index].selected = true;
  const { label: area = "" } = item;
  emits("areaChange", area);
};

const getParams = () => {
  const params = { ...searchParams };
  return { ...params };
};

const initdatOption = () => {
  datOption.forEach(item => {
    item.disabled = dataTypes.value.length < 2 && dataTypes.value.includes(item.label);
  });
};

watch(
  () => dataTypes.value,
  (newVal, oldVal) => {
    datOption.forEach(item => {
      item.disabled = true;
    });
    setTimeout(() => {
      datOption.forEach(item => {
        item.disabled = dataTypes.value.length < 2 && dataTypes.value.includes(item.label);
      });
    }, 1500);
    if (newVal.length === 1 && oldVal.length === 0) {
      // 判断 是否从全不选到选择
      emits("change", getParams(), dataTypes.value, false, true, true);
    } else {
      emits("change", getParams(), dataTypes.value, false, true);
    }
    emits("typeChange", dataTypes.value);
  }
);

onMounted(async () => {
  initDate();
  await initTreeData(props.parameter);
  await initAreaData(searchParams.parameter);
  initdatOption();
  emits("change", getParams(), dataTypes.value, true);
  emits("selectChange", defaultparameter.value);
});

defineExpose({
  params: searchParams,
  getParams
});
</script>

<template>
  <div v-loading="loading" class="search">
    <div class="title">时间选择</div>
    <div class="form">
      <px-select v-model="period" @change="periodChangeHandler">
        <px-option v-for="item in periodOption" :key="item.value" :disabled="item.disabled" :label="item.label" :value="item.value" />
      </px-select>
      <br />
      <px-date-picker
        v-model="searchParams.startTime"
        type="datetime"
        :editable="false"
        :clearable="false"
        format="YYYY/MM/DD HH:mm"
        value-format="YYYY-MM-DD HH:mm:ss"
        :default-time="new Date(2000, 1, 1, 0, 0, 0)"
        :disabled-date="startDisabledDateFn"
        placeholder="开始时间"
        @change="startTimeChangeHandler"
      />
      <br />
      <px-date-picker
        v-model="searchParams.endTime"
        type="datetime"
        :editable="false"
        :clearable="false"
        format="YYYY/MM/DD HH:mm"
        value-format="YYYY-MM-DD HH:mm:ss"
        :default-time="new Date(2000, 1, 1, 23, 59, 59)"
        :disabled-date="endDisabledDateFn"
        placeholder="结束时间"
        @change="endTimeChangeHandler"
      />
    </div>
    <div class="title">物料选择</div>
    <div class="form">
      <px-tree-select
        ref="cascaderTreeRef"
        v-model="searchParams.parameter"
        popper-class="parameter-tree-select"
        :data="treeData"
        node-key="code"
        :default-expanded-keys="defaultExpandedKeys"
        accordion
        highlight-current
        :props="defaultProps"
        filterable
        placeholder="请选择物料"
        @current-change="parameterChangeHandler"
      />
    </div>
    <div v-if="type === 'craft'" class="title">区域</div>
    <div v-if="type === 'craft'" class="form area-content">
      <div
        v-for="(item, index) in realAreaes"
        :key="item.label"
        :class="['area-item', item.selected ? 'area-item-selected' : '']"
        @click="areaChangeHandler(item, index)"
      >
        <div class="area-item-label">{{ item.label }}</div>
        <div class="area-item-tag" :style="{ backgroundColor: item.backgroundColor }" />
      </div>
    </div>
    <div class="title">数据选择</div>
    <div class="form">
      <px-checkbox-group v-model="dataTypes" :disabled="dataTypesDisabled">
        <px-checkbox v-for="d in datOption" :key="d.value" :disabled="d.disabled" :label="d.label">{{ d.label }}</px-checkbox>
      </px-checkbox-group>
    </div>
  </div>
</template>

<style lang="scss">
.parameter-tree-select {
  .px-select-dropdown {
    .px-select-dropdown__item {
      color: var(--px-color-primary);

      &.is-disabled {
        color: #999 !important;
      }

      &.selected {
        font-weight: 600;
      }
    }
  }

  .px-tree > .px-tree-node > .px-tree-node__content > .px-select-dropdown__item {
    &.is-disabled {
      color: #555 !important;
    }
  }
}
</style>

<style lang="scss" scoped>
.search {
  $form_width: 150px;

  .title {
    margin-top: 22px;
    margin-bottom: 12px;
    font-weight: 600;
    color: #333;

    &:first-of-type {
      margin-top: 0;
    }
  }

  .form {
    .px-input,
    .px-select {
      width: $form_width;
    }

    :deep(.px-date-editor) {
      width: $form_width !important;
      margin-top: 8px;
    }

    .px-checkbox {
      display: flex;
      align-items: center;
    }
  }

  .area-content {
    display: grid;
    grid-template-columns: repeat(1, 1fr);

    .area-item {
      box-sizing: border-box;
      display: flex;
      gap: 8px;
      align-items: center;
      justify-content: space-between;
      height: 26px;
      padding: 0 8px;

      .area-item-label {
        font-size: 12px;
        font-weight: 600;
        line-height: 1;
        color: var(--px-color-primary);
      }

      .area-item-tag {
        width: 12px;
        height: 8px;
        background-color: #ddd;
      }

      &:hover {
        cursor: pointer;
        background-color: #f6f6f6;
      }
    }

    .area-item-selected {
      background-color: #f6f6f6;
    }
  }
}
</style>
